package own.stu.jobgib.playown.basic.generic;

import java.io.Serializable;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/*
 * TypeVariable是类型变量，如参数化类型中的E、K等类型变量，
 * 表示泛指任何类，如果加上extends/super限定，则就会有相应的上限、下限。
 *
 * */
public class TypeVariableTest<K extends List & Serializable, V> {


    public static void main(String[] args) {

        TypeVariable[] v = new TypeVariableTest().getClass().getTypeParameters();

        for (TypeVariable t : v) {
            System.out.println(Arrays.stream(t.getBounds()).map(Type::getTypeName).collect(Collectors.toList()));
            System.out.println(t.getName());
            System.out.println(t.getGenericDeclaration());
            System.out.println("-----------------");
        }

        TypeVariableTest<ArrayList<Integer>, Integer> data = new TypeVariableTest();

        System.out.println("================");

        v = data.getClass().getTypeParameters();
        for (TypeVariable t : v) {
            System.out.println(Arrays.stream(t.getBounds()).map(Type::getTypeName).collect(Collectors.toList()));
            System.out.println(t.getName());
            System.out.println(t.getGenericDeclaration());
            System.out.println("-----------------");
        }

    }

//    public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
//        /**
//         * 获得该类型变量的上限（上边界），若无显式定义（extends），默认为Object，类型变量的上限可能不止一个，因为可以用&符号限定多个（这其中有且只能有一个为类或抽象类，且必须放在extends后的第一个，即若有多个上边界，则第一个&后必为接口）
//         * 比如 xxxClass<K extends List & Serialize>,则返回 List和Serialize
//         */
//        Type[] getBounds();
//
//        /**
//         *  获取的是在哪个类上进行的泛型声明,在如上的例子中,返回的是xxxClass
//         * @since 1.5
//         */
//        D getGenericDeclaration();
//
//        /**
//         *  同样是上面的例子,返回 K, 也就是泛型类型声明时写的名字
//         */
//        String getName();
//
//        /**
//         *
//         * @since 1.8
//         */
//        AnnotatedType[] getAnnotatedBounds();
//    }

}
